/**
 * Copyright (C) 2018-2020
 * All rights reserved, Designed By www.yixiang.co
 * 注意：
 * 本软件为www.yixiang.co开发研制，未经购买不得使用
 * 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
 * 一经发现盗用、分享等行为，将追究法律责任，后果自负
 */
package co.yixiang.modules.services;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import co.y.t.hyfPay.Config;
import co.y.t.hyfPay.HttpClient;
import co.y.t.hyfPay.Safe;
import co.yixiang.api.YshopException;
import co.yixiang.enums.AppFromEnum;
import co.yixiang.enums.BillDetailEnum;
import co.yixiang.enums.OrderInfoEnum;
import co.yixiang.enums.OrderLogEnum;
import co.yixiang.enums.PayTypeEnum;
import co.yixiang.modules.activity.domain.YxStoreBargainUser;
import co.yixiang.modules.activity.domain.YxStoreCombination;
import co.yixiang.modules.activity.service.YxStoreBargainUserService;
import co.yixiang.modules.activity.service.YxStoreCombinationService;
import co.yixiang.modules.activity.service.YxStorePinkService;
import co.yixiang.modules.cart.vo.YxStoreCartQueryVo;
import co.yixiang.modules.order.domain.YxStoreOrder;
import co.yixiang.modules.order.domain.YxStoreOrderCartInfo;
import co.yixiang.modules.order.dto.OrderExtendDto;
import co.yixiang.modules.order.param.ComputeOrderParam;
import co.yixiang.modules.order.service.YxStoreOrderCartInfoService;
import co.yixiang.modules.order.service.YxStoreOrderService;
import co.yixiang.modules.order.service.dto.ProductAttrDto;
import co.yixiang.modules.order.service.dto.ProductDto;
import co.yixiang.modules.order.vo.OrderCartInfoVo;
import co.yixiang.modules.order.vo.YxStoreOrderQueryVo;
import co.yixiang.modules.mp.service.WeixinPayService;
import co.yixiang.modules.shop.rest.CommissionMainController;
import co.yixiang.modules.shop.rest.CommissionNewController;
import co.yixiang.modules.shop.rest.TDMQMessageController;
import co.yixiang.modules.user.domain.ShoppingPayform;
import co.yixiang.modules.user.domain.YxUser;
import co.yixiang.modules.user.service.ShoppingPayformService;
import co.yixiang.modules.user.service.YxUserService;
import co.yixiang.modules.user.service.dto.WechatUserDto;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.order.WxPayMwebOrderResult;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * @ClassName 订单提供者服务
 * @Author hupeng <610796224@qq.com>
 * @Date 2020/6/22
 **/
@Slf4j
@Service
@AllArgsConstructor
public class OrderSupplyService {

    private final YxStoreOrderService storeOrderService;
    private final YxStoreBargainUserService storeBargainUserService;
    private final YxStorePinkService storePinkService;
    private final YxStoreOrderCartInfoService orderCartInfoService;
    private final WeixinPayService weixinPayService;
    private final co.yixiang.modules.shop.rest.CommissionMainController CommissionMainController;
    private final co.yixiang.modules.shop.rest.TDMQMessageController TDMQMessageController;
    private final co.yixiang.modules.shop.rest.CommissionNewController CommissionNewController;
    private final YxUserService yxUserService;
    private final ShoppingPayformService shoppingPayformService;
    private final YxStoreCombinationService storeCombinationService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    /*private final TDMQMessageController tdmqMessage;*/

    /**
     * 返回订单产品信息
     * @param unique 订单唯一值
     * @return OrderCartInfoVo
     */
    public OrderCartInfoVo getProductOrder(String unique){
        YxStoreOrderCartInfo orderCartInfo = orderCartInfoService.findByUni(unique);

        YxStoreCartQueryVo cartInfo = JSONObject.parseObject(orderCartInfo.getCartInfo(),
                YxStoreCartQueryVo.class);

        ProductDto productDTO = new ProductDto();
        productDTO.setImage(cartInfo.getProductInfo().getImage());
        productDTO.setPrice(cartInfo.getProductInfo().getPrice().doubleValue());
        productDTO.setStoreName(cartInfo.getProductInfo().getStoreName());
        if(ObjectUtil.isNotEmpty(cartInfo.getProductInfo().getAttrInfo())){
            ProductAttrDto productAttrDTO = new ProductAttrDto();
            productAttrDTO.setImage(cartInfo.getProductInfo().getAttrInfo().getImage());
            productAttrDTO.setPrice(cartInfo.getProductInfo().getAttrInfo().getPrice().doubleValue());
            productAttrDTO.setProductId(cartInfo.getProductInfo().getAttrInfo().getProductId());
            productAttrDTO.setSku(cartInfo.getProductInfo().getAttrInfo().getSku());
            productDTO.setAttrInfo(productAttrDTO);
        }


        return OrderCartInfoVo.builder()
                .bargainId(cartInfo.getBargainId())
                .cartNum(cartInfo.getCartNum())
                .combinationId(cartInfo.getCombinationId())
                .orderId(storeOrderService.getById(orderCartInfo.getOid()).getOrderId())
                .seckillId(cartInfo.getSeckillId())
                .productInfo(productDTO)
                .build();
    }

    /**
     * 订单检测
     * @param uid uid
     * @param key 缓存值
     * @param param ComputeOrderParam
     * @return map
     */
    public Map<String,Object> check(Long uid,String key, ComputeOrderParam param){
        Map<String,Object> map = Maps.newHashMap();
        if(StrUtil.isBlank(key)) {
            throw new YshopException("参数错误");
        }
        YxStoreOrderQueryVo storeOrder = storeOrderService.getOrderInfo(key,uid);
        if(ObjectUtil.isNotNull(storeOrder)){

            OrderExtendDto orderExtendDTO = OrderExtendDto.builder()
                    .key(key)
                    .orderId(storeOrder.getOrderId())
                    .build();
            map.put("status", OrderLogEnum.EXTEND_ORDER.getValue());
            map.put("result", orderExtendDTO);
            map.put("msg",OrderLogEnum.EXTEND_ORDER.getDesc());
        }

        // 砍价
        if(StrUtil.isNotBlank(param.getBargainId()) && NumberUtil.isNumber(param.getBargainId())){
            Long bargainId = Long.valueOf(param.getBargainId());
            if(bargainId > 0){
                YxStoreBargainUser storeBargainUser = storeBargainUserService
                        .getBargainUserInfo(bargainId,uid);
                if(storeBargainUser == null) {
                    throw new YshopException("砍价失败");
                }
                if(OrderInfoEnum.BARGAIN_STATUS_3.getValue().equals(storeBargainUser.getStatus())) {
                    throw new YshopException("砍价已支付");
                }
            }

        }
        // 拼团
        if(StrUtil.isNotBlank(param.getCombinationId()) && NumberUtil.isNumber(param.getCombinationId())){
            Long combinationId = Long.valueOf(param.getCombinationId());
            if(combinationId > 0){
                YxStoreCombination storeCombination =storeCombinationService.getById(combinationId);
                //拼团类型为推三返一
                if("1".equals(storeCombination.getCombinationType())){
                    String count =orderCartInfoService.getOrderCountByRebate(uid,combinationId,storeCombination.getProductId());
                    if(Integer.parseInt(count) >0){
                        YxStoreOrder yxStoreOrder = storeOrderService.getOrderRebate(combinationId,uid);
                        map.put("status",OrderLogEnum.PINK_ORDER_FAIL_3.getValue());
                        OrderExtendDto orderExtendDTO = new OrderExtendDto();
                        orderExtendDTO.setOrderId(yxStoreOrder.getOrderId());
                        map.put("result",orderExtendDTO);
                        map.put("msg",OrderLogEnum.PINK_ORDER_FAIL_3.getDesc());
                    }
                }else{
                    if(StrUtil.isNotBlank(param.getPinkId()) && NumberUtil.isNumber(param.getPinkId())){
                        Long pinkId = Long.valueOf(param.getPinkId());
                        if(pinkId > 0){
                            YxStoreOrder yxStoreOrder = storeOrderService.getOrderPink(pinkId,uid);
                            if(yxStoreOrder != null){
                                map.put("status",OrderLogEnum.PINK_ORDER_FAIL_1.getValue());
                                OrderExtendDto orderExtendDTO = new OrderExtendDto();
                                orderExtendDTO.setOrderId(yxStoreOrder.getOrderId());
                                map.put("result",orderExtendDTO);
                                map.put("msg",OrderLogEnum.PINK_ORDER_FAIL_1.getDesc());
                            }
                            if(yxStoreOrder != null && storePinkService.getIsPinkUid(pinkId,uid)){
                                map.put("status",OrderLogEnum.PINK_ORDER_FAIL_2.getValue());
                                OrderExtendDto orderExtendDTO = new OrderExtendDto();
                                orderExtendDTO.setOrderId(yxStoreOrder.getOrderId());
                                map.put("result",orderExtendDTO);
                                map.put("msg",OrderLogEnum.PINK_ORDER_FAIL_2.getDesc());
                            }
                        }

                    }
                }
            }
        }

// 无上级则购买订单失败
        YxUser user =yxUserService.getById(uid);
        if(!"Y".equals(user.getIsNoSpread()) && user.getSpreadUid() ==0){
            /*map.put("status", OrderLogEnum.ORDER_FAIL_NO_SPREAD.getValue());
            map.put("msg",OrderLogEnum.ORDER_FAIL_NO_SPREAD.getDesc());*/
            throw new YshopException("订单生成失败，没有上级无法支付订单");

        }

        return map;
    }

    /**
     * 支付
     * @param map     map
     * @param orderId 订单号
     * @param uid     uid
     * @param payType 支付方式
     * @param from 来源
     * @param orderDTO orderDTO
     * @return map
     */
    public Map<String, Object> goPay(Map<String, Object> map, String orderId, Long uid, String payType,
                                     String from, OrderExtendDto orderDTO){
        System.out.println("payType=======" + payType);
        switch (PayTypeEnum.toType(payType)) {
            case WEIXIN:
                Map<String, String> jsConfig = new HashMap<>();
                if (AppFromEnum.WEIXIN_H5.getValue().equals(from)) {
                    WxPayMwebOrderResult wxPayMwebOrderResult = (WxPayMwebOrderResult) weixinPayService
                            .unifyPay(orderId, from, BillDetailEnum.TYPE_3.getValue(), "H5商品购买");

                    log.info("wxPayMwebOrderResult:{}", wxPayMwebOrderResult);
                    jsConfig.put("mweb_url", wxPayMwebOrderResult.getMwebUrl());
                    orderDTO.setJsConfig(jsConfig);
                    map.put("result", orderDTO);
                    map.put("status", "WECHAT_H5_PAY");
                    map.put("payMsg", "订单创建成功");
                    return map;
                } else if (AppFromEnum.ROUNTINE.getValue().equals(from)) {
                    map.put("status", "WECHAT_PAY");
                    WxPayMpOrderResult wxPayMpOrderResult = (WxPayMpOrderResult) weixinPayService
                            .unifyPay(orderId, from, BillDetailEnum.TYPE_3.getValue(), "小程序商品购买");
                    jsConfig.put("appId", wxPayMpOrderResult.getAppId());
                    jsConfig.put("timeStamp", wxPayMpOrderResult.getTimeStamp());
                    jsConfig.put("paySign", wxPayMpOrderResult.getPaySign());
                    jsConfig.put("nonceStr", wxPayMpOrderResult.getNonceStr());
                    jsConfig.put("package", wxPayMpOrderResult.getPackageValue());
                    jsConfig.put("signType", wxPayMpOrderResult.getSignType());
                    orderDTO.setJsConfig(jsConfig);
                    map.put("payMsg", "订单创建成功");
                    map.put("result", orderDTO);
                    return map;
                    //汇卡支付
                    /*BigDecimal bigDecimal1 = new BigDecimal(100);
                    int payPrice1 = 0;
                    String goods1 = "客户付款";
                    map.put("status", "HYF_PAY_MINI");
                    YxStoreOrderQueryVo orderInfo1 = storeOrderService.getOrderInfo(orderId, null);
                    if (ObjectUtil.isNull(orderInfo1)) {
                        throw new YshopException("订单不存在");
                    }
                    if (orderInfo1.getPaid().equals(OrderInfoEnum.PAY_STATUS_1.getValue())) {
                        throw new YshopException("该订单已支付");
                    }

                    if (orderInfo1.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
                        throw new YshopException("该支付无需支付");
                    }

                    //uid = orderInfo.getUid().intValue();
                    //计算分
                    //payPrice = bigDecimal.multiply(orderInfo.getPayPrice()).intValue();
                    payPrice1 = bigDecimal1.multiply(new BigDecimal("0.01")).intValue();
                    ShoppingPayform pf1 = new ShoppingPayform();
                    pf1.setTotalprice(orderInfo1.getPayPrice());
                    pf1.setDeletestatus(false);
                    pf1.setUid(uid);
                    pf1.setPayType("小程序汇卡支付");
                    pf1.setPayno("HF-"+orderId);
                    pf1.setOrderId(orderId);
                    pf1.setPaystatus("未支付");
                    shoppingPayformService.save(pf1);
                    //map.put("result",orderDTO);
                    map.put("payMsg", "订单创建成功");
                    YxUser yxUser = yxUserService.getById(uid);
                    WechatUserDto wechatUser = yxUser.getWxProfile();
                    String openid = wechatUser.getRoutineOpenid();
                    String returnUrl1 = Config.returnUrl;  // 前台返回页面：以商家自己的网站为准
                    String notifyUrl1 = Config.notifyUrl; // 后端通知页面：以商家自己的网站为准
                    // POST请求参数：按签名顺序，有序存放
                    TreeMap<String, String> paramss = new TreeMap<String, String>();
                    paramss.put("amount", Long.toString(payPrice1)); // 金额单位为“分”
                    paramss.put("backEndUrl", notifyUrl1);
                    paramss.put("bizType", "814"); // 商家自定义的业务类别
                    paramss.put("frontEndUrl", returnUrl1);
                    paramss.put("goodsName", goods1); // 商家自定义的货物名称，该字段不需参加签名
                    paramss.put("hicardMerchNo", Config.merchNo);
                    paramss.put("isT0", "1");
                    //params.put("merchOrderNo", vo.getRechargeBillId()); // 商家自定义的订单号
                    paramss.put("merchOrderNo", pf1.getPayno());
                    paramss.put("openId", openid);
                    paramss.put("organNo", Config.organNo);
                    paramss.put("payType", "014");
                    paramss.put("showPage", "0"); // 固定
                    paramss.put("subAppId", Config.appid);
                    paramss.put("version", Config.version);
                    paramss.put("sign", Safe.sign4mini(paramss)); // 签名
                    paramss.put("remark", "");
                    paramss.put("transIP", ""); // 该字段不需参加签名
                    paramss.put("reserved", ""); // 该字段不需参加签名

                    // params.put("isT0", "1");

                    com.alibaba.fastjson.JSONObject jo1 = new com.alibaba.fastjson.JSONObject();
                    jo1.putAll(paramss);

                    String json1 = jo1.toString();
                    System.out.println("发送数据：" + json1);
                    log.info("发送数据：" + json1);
                    String url1 = "http://" + Config.payIPAddress
                            + "/hicardpay/order/create";
                    String resp1 = HttpClient.post(json1, url1);
                    System.out.println("返回数据：" + resp1);
                    log.info("返回数据：" + resp1);
                    com.alibaba.fastjson.JSONObject resJo1 = com.alibaba.fastjson.JSONObject.parseObject(resp1);
                    System.out.println("resJo=======" + resJo1);
                    log.info("resJo=======" + resJo1);
                    // 验证签名
                    // 返回数据：{"html":"","version":"V003","sign":"5d81096366913ec56c0e4fe121ff592e","hicardMerchNo":"104401569102119","amount":"1","createTime":"2018-01-16 22:20:51","qrURL":"","merchOrderNo":"f6edc266-a0b0-4016-a235-2035d73cecb3","payType":"014","payInfo":"http://ymftest.hi-card.cn/hicardqrcode/qrCode/jsapi/Host6?orderNo=4161801160103314","respCode":"00","organNo":"12999000","respMsg":"处理成功","hicardOrderNo":"4161801160103314"}
                    TreeMap<String, String> paramss2 = new TreeMap<String, String>();
                    paramss2.put("amount", Long.toString(resJo1.getLong("amount")));
                    paramss2.put("createTime", resJo1.getString("createTime"));
                    paramss2.put("hicardMerchNo", resJo1.getString("hicardMerchNo"));
                    paramss2.put("hicardOrderNo", resJo1.getString("hicardOrderNo"));
                    if (resJo1.containsKey("html")) {
                        paramss2.put("html", resJo1.getString("html"));
                    }
                    if (resJo1.containsKey("isT0")) {
                        paramss2.put("isT0", resJo1.getString("isT0"));
                    }
                    paramss2.put("merchOrderNo", resJo1.getString("merchOrderNo"));
                    paramss2.put("organNo", resJo1.getString("organNo"));
                    paramss2.put("payInfo", resJo1.getString("payInfo"));
                    paramss2.put("payType", resJo1.getString("payType"));
                    if (resJo1.containsKey("qrURL")) {
                        paramss2.put("qrURL", resJo1.getString("qrURL"));
                    }
                    paramss2.put("respCode", resJo1.getString("respCode"));
                    paramss2.put("respMsg", resJo1.getString("respMsg"));
                    if (resJo1.containsKey("showPage")) {
                        paramss2.put("showPage", resJo1.getString("showPage"));
                    }

                    paramss2.put("version", resJo1.getString("version"));
                    //params2.put("subAppId", resJo.getString("subAppId"));
                    String myRSign1 = Safe.sign(paramss2);
                    String rSign1 = resJo1.getString("sign");
                    Map<String, String> resultMap = new HashMap<>();
		*//*if (!myRSign.equals(rSign)) {
			resultMap.put("payState", "fail");
			resultMap.put("message", "签名异常，支付失败!");
			resultMap.put("payUrl", resJo.getString("payInfo"));
		} else {*//*
                    if ("00".equals(resJo1.getString("respCode"))) {

                        String payUrl = resJo1.getString("payInfo");
                        JSONObject jsonObject =JSONObject.parseObject(payUrl);
                        System.out.println("payUrl=======" + payUrl);
                        System.out.println("jsonObject=======" + jsonObject);
                        //map.put("payState", "success");
                        //map.put("payUrl", payUrl);
                        map.put("status", "WECHAT_PAY");
                        resultMap.put("appId", jsonObject.getString("appId"));
                        resultMap.put("timeStamp", jsonObject.getString("timeStamp"));
                        resultMap.put("paySign", jsonObject.getString("paySign"));
                        resultMap.put("nonceStr", jsonObject.getString("nonceStr"));
                        resultMap.put("package", jsonObject.getString("package"));
                        resultMap.put("signType", jsonObject.getString("signType"));
                        orderDTO.setJsConfig(resultMap);
                        map.put("payMsg", "订单创建成功");
                        map.put("result", orderDTO);
                        return map;
                        // response.sendRedirect(payUrl);
                    }*/
                } else if (AppFromEnum.APP.getValue().equals(from)) {//app支付
                    map.put("status", "WECHAT_APP_PAY");
                    WxPayAppOrderResult wxPayAppOrderResult = (WxPayAppOrderResult) weixinPayService
                            .unifyPay(orderId, from, BillDetailEnum.TYPE_3.getValue(), "APP商品购买");
                    jsConfig.put("appid", wxPayAppOrderResult.getAppId());
                    jsConfig.put("partnerid", wxPayAppOrderResult.getPartnerId());
                    jsConfig.put("prepayid", wxPayAppOrderResult.getPrepayId());
                    jsConfig.put("package", wxPayAppOrderResult.getPackageValue());
                    jsConfig.put("noncestr", wxPayAppOrderResult.getNonceStr());
                    jsConfig.put("timestamp", wxPayAppOrderResult.getTimeStamp());
                    jsConfig.put("sign", wxPayAppOrderResult.getSign());
                    orderDTO.setJsConfig(jsConfig);
                    map.put("result", orderDTO);
                    map.put("payMsg", "订单创建成功");
                    return map;
                } else {//公众号
                    map.put("status", "WECHAT_PAY");
                    WxPayMpOrderResult wxPayMpOrderResult = (WxPayMpOrderResult) weixinPayService
                            .unifyPay(orderId, from, BillDetailEnum.TYPE_3.getValue(), "公众号商品购买");

                    log.info("WxPayMpOrderResult:{}", wxPayMpOrderResult);

                    jsConfig.put("appId", wxPayMpOrderResult.getAppId());
                    jsConfig.put("timestamp", wxPayMpOrderResult.getTimeStamp());
                    jsConfig.put("nonceStr", wxPayMpOrderResult.getNonceStr());
                    jsConfig.put("package", wxPayMpOrderResult.getPackageValue());
                    jsConfig.put("signType", wxPayMpOrderResult.getSignType());
                    jsConfig.put("paySign", wxPayMpOrderResult.getPaySign());
                    orderDTO.setJsConfig(jsConfig);
                    map.put("result", orderDTO);
                    map.put("payMsg", "订单创建成功");

                    return map;
                }
            case YUE:
                storeOrderService.yuePay(orderId, uid);

                YxStoreOrderQueryVo order = storeOrderService.getOrderInfo(orderId, uid);
                //log.info("orderId=============" + order.getId());
                //CommissionMainController.checkOrderGoodsclass(order.getId().toString());
                //CommissionNewController.checkOrderGoodsclass(order.getId().toString());
                //TDMQMessageController.tdmqMessage(order.getId().toString());
                /*tdmqMessage.tdmqMessage(order.getId().toString());*/
                map.put("payMsg", "余额支付成功");
                return map;
            case FUG:
                storeOrderService.fugPay(orderId, uid);

                /*order = storeOrderService.getOrderInfo(orderId, uid);
                log.info("orderId=============" + order.getId());
                //CommissionMainController.checkOrderGoodsclass(order.getId().toString());
                TDMQMessageController.tdmqMessage(order.getId().toString());*/
                map.put("payMsg", "复购支付成功");
                return map;
            case HYF:
                BigDecimal bigDecimal = new BigDecimal(100);
                int payPrice = 0;
                String goods = "客户付款";
                map.put("status", "HYF_PAY");
                YxStoreOrderQueryVo orderInfo = storeOrderService.getOrderInfo(orderId, null);
                if (ObjectUtil.isNull(orderInfo)) {
                    throw new YshopException("订单不存在");
                }
                if (orderInfo.getPaid().equals(OrderInfoEnum.PAY_STATUS_1.getValue())) {
                    throw new YshopException("该订单已支付");
                }

                if (orderInfo.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
                    throw new YshopException("该支付无需支付");
                }

                //uid = orderInfo.getUid().intValue();
                //计算分
                //payPrice = bigDecimal.multiply(orderInfo.getPayPrice()).intValue();
                payPrice = bigDecimal.multiply(new BigDecimal("0.01")).intValue();
                ShoppingPayform pf = new ShoppingPayform();
                pf.setTotalprice(orderInfo.getPayPrice());
                pf.setDeletestatus(false);
                pf.setUid(uid);
                pf.setPayType("汇卡支付");
                pf.setPayno(System.currentTimeMillis()+"-"+orderId);
                pf.setOrderId(orderId);
                pf.setPaystatus("未支付");
                shoppingPayformService.save(pf);
                //map.put("result",orderDTO);
                map.put("payMsg", "订单创建成功");

                String returnUrl = Config.returnUrl;  // 前台返回页面：以商家自己的网站为准
                String notifyUrl = Config.notifyUrl; // 后端通知页面：以商家自己的网站为准
                // POST请求参数：按签名顺序，有序存放
                TreeMap<String, String>  params = new TreeMap<String, String> ();
                params.put("amount", Long.toString(payPrice)); // 金额单位为“分”
                params.put("backEndUrl", notifyUrl);
                params.put("bizType", "814"); // 商家自定义的业务类别
                params.put("frontEndUrl", returnUrl);
                params.put("goodsName", goods); // 商家自定义的货物名称，该字段不需参加签名
                params.put("hicardMerchNo", Config.merchNo);
                params.put("isT0", "1");
                //params.put("merchOrderNo", vo.getRechargeBillId()); // 商家自定义的订单号
                params.put("merchOrderNo", pf.getPayno());
                params.put("organNo", Config.organNo);
                params.put("payType", "014");
                params.put("showPage", "0"); // 固定
                params.put("version", Config.version);
                params.put("sign", Safe.sign(params)); // 签名
                params.put("subAppId", "");
                params.put("remark", "");
                params.put("transIP", ""); // 该字段不需参加签名
                params.put("reserved", ""); // 该字段不需参加签名

                // params.put("isT0", "1");

                com.alibaba.fastjson.JSONObject jo = new com.alibaba.fastjson.JSONObject();
                jo.putAll(params);

                String json = jo.toString();
                System.out.println("发送数据：" + json);
                log.info("发送数据：" + json);
                String url = "http://" + Config.payIPAddress
                        + "/hicardpay/order/create";
                String resp = HttpClient.post(json, url);
                System.out.println("返回数据：" + resp);
                log.info("返回数据：" + resp);
                com.alibaba.fastjson.JSONObject resJo = com.alibaba.fastjson.JSONObject.parseObject(resp);
                System.out.println("resJo=======" + resJo);
                log.info("resJo=======" + resJo);
                // 验证签名
                // 返回数据：{"html":"","version":"V003","sign":"5d81096366913ec56c0e4fe121ff592e","hicardMerchNo":"104401569102119","amount":"1","createTime":"2018-01-16 22:20:51","qrURL":"","merchOrderNo":"f6edc266-a0b0-4016-a235-2035d73cecb3","payType":"014","payInfo":"http://ymftest.hi-card.cn/hicardqrcode/qrCode/jsapi/Host6?orderNo=4161801160103314","respCode":"00","organNo":"12999000","respMsg":"处理成功","hicardOrderNo":"4161801160103314"}
                TreeMap<String, String>  params2 = new TreeMap<String, String> ();
                params2.put("amount", Long.toString(resJo.getLong("amount")));
                params2.put("createTime", resJo.getString("createTime"));
                params2.put("hicardMerchNo", resJo.getString("hicardMerchNo"));
                params2.put("hicardOrderNo", resJo.getString("hicardOrderNo"));
                if (resJo.containsKey("html")) {
                    params2.put("html", resJo.getString("html"));
                }
                if (resJo.containsKey("isT0")) {
                    params2.put("isT0", resJo.getString("isT0"));
                }
                params2.put("merchOrderNo", resJo.getString("merchOrderNo"));
                params2.put("organNo", resJo.getString("organNo"));
                params2.put("payInfo", resJo.getString("payInfo"));
                params2.put("payType", resJo.getString("payType"));
                if (resJo.containsKey("qrURL")) {
                    params2.put("qrURL", resJo.getString("qrURL"));
                }
                params2.put("respCode", resJo.getString("respCode"));
                params2.put("respMsg", resJo.getString("respMsg"));
                if (resJo.containsKey("showPage")) {
                    params2.put("showPage", resJo.getString("showPage"));
                }

                params2.put("version", resJo.getString("version"));
                String myRSign = Safe.sign(params2);
                String rSign = resJo.getString("sign");
		/*if (!myRSign.equals(rSign)) {
			resultMap.put("payState", "fail");
			resultMap.put("message", "签名异常，支付失败!");
			resultMap.put("payUrl", resJo.getString("payInfo"));
		} else {*/
                if ("00".equals(resJo.getString("respCode"))) {

                    String payUrl = resJo.getString("payInfo");
                    System.out.println("payUrl=======" + payUrl);
                    map.put("result", orderDTO);
                    map.put("payState", "success");
                    map.put("payUrl", payUrl);
                    // response.sendRedirect(payUrl);
                }
                return map;
            case HYFMINI:
                bigDecimal = new BigDecimal(100);
                payPrice = 0;
                goods = "客户付款";
                map.put("status", "HYF_PAY_MINI");
                orderInfo = storeOrderService.getOrderInfo(orderId, null);
                if (ObjectUtil.isNull(orderInfo)) {
                    throw new YshopException("订单不存在");
                }
                if (orderInfo.getPaid().equals(OrderInfoEnum.PAY_STATUS_1.getValue())) {
                    throw new YshopException("该订单已支付");
                }

                if (orderInfo.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
                    throw new YshopException("该支付无需支付");
                }

                //uid = orderInfo.getUid().intValue();
                //计算分
                //payPrice = bigDecimal.multiply(orderInfo.getPayPrice()).intValue();
                payPrice = bigDecimal.multiply(new BigDecimal("0.01")).intValue();
                pf = new ShoppingPayform();
                pf.setTotalprice(orderInfo.getPayPrice());
                pf.setDeletestatus(false);
                pf.setUid(uid);
                pf.setPayType("小程序汇卡支付");
                pf.setPayno("HF-"+orderId);
                pf.setOrderId(orderId);
                pf.setPaystatus("未支付");
                shoppingPayformService.save(pf);
                //map.put("result",orderDTO);
                map.put("payMsg", "订单创建成功");
                YxUser yxUser = yxUserService.getById(uid);
                WechatUserDto wechatUser = yxUser.getWxProfile();
                String openid = wechatUser.getRoutineOpenid();
                returnUrl = Config.returnUrl;  // 前台返回页面：以商家自己的网站为准
                notifyUrl = Config.notifyUrl; // 后端通知页面：以商家自己的网站为准
                // POST请求参数：按签名顺序，有序存放
                params = new TreeMap<String, String>();
                params.put("amount", Long.toString(payPrice)); // 金额单位为“分”
                params.put("backEndUrl", notifyUrl);
                params.put("bizType", "814"); // 商家自定义的业务类别
                params.put("frontEndUrl", returnUrl);
                params.put("goodsName", goods); // 商家自定义的货物名称，该字段不需参加签名
                params.put("hicardMerchNo", Config.merchNo);
                params.put("isT0", "1");
                //params.put("merchOrderNo", vo.getRechargeBillId()); // 商家自定义的订单号
                params.put("merchOrderNo", pf.getPayno());
                params.put("openId", openid);
                params.put("organNo", Config.organNo);
                params.put("payType", "014");
                params.put("showPage", "0"); // 固定
                params.put("subAppId", Config.appid);
                params.put("version", Config.version);
                params.put("sign", Safe.sign4mini(params)); // 签名
                params.put("remark", "");
                params.put("transIP", ""); // 该字段不需参加签名
                params.put("reserved", ""); // 该字段不需参加签名

                // params.put("isT0", "1");

                jo = new com.alibaba.fastjson.JSONObject();
                jo.putAll(params);

                json = jo.toString();
                System.out.println("发送数据：" + json);
                log.info("发送数据：" + json);
                url = "http://" + Config.payIPAddress
                        + "/hicardpay/order/create";
                resp = HttpClient.post(json, url);
                System.out.println("返回数据：" + resp);
                log.info("返回数据：" + resp);
                resJo = com.alibaba.fastjson.JSONObject.parseObject(resp);
                System.out.println("resJo=======" + resJo);
                log.info("resJo=======" + resJo);
                // 验证签名
                // 返回数据：{"html":"","version":"V003","sign":"5d81096366913ec56c0e4fe121ff592e","hicardMerchNo":"104401569102119","amount":"1","createTime":"2018-01-16 22:20:51","qrURL":"","merchOrderNo":"f6edc266-a0b0-4016-a235-2035d73cecb3","payType":"014","payInfo":"http://ymftest.hi-card.cn/hicardqrcode/qrCode/jsapi/Host6?orderNo=4161801160103314","respCode":"00","organNo":"12999000","respMsg":"处理成功","hicardOrderNo":"4161801160103314"}
                params2 = new TreeMap<String, String>();
                params2.put("amount", Long.toString(resJo.getLong("amount")));
                params2.put("createTime", resJo.getString("createTime"));
                params2.put("hicardMerchNo", resJo.getString("hicardMerchNo"));
                params2.put("hicardOrderNo", resJo.getString("hicardOrderNo"));
                if (resJo.containsKey("html")) {
                    params2.put("html", resJo.getString("html"));
                }
                if (resJo.containsKey("isT0")) {
                    params2.put("isT0", resJo.getString("isT0"));
                }
                params2.put("merchOrderNo", resJo.getString("merchOrderNo"));
                params2.put("organNo", resJo.getString("organNo"));
                params2.put("payInfo", resJo.getString("payInfo"));
                params2.put("payType", resJo.getString("payType"));
                if (resJo.containsKey("qrURL")) {
                    params2.put("qrURL", resJo.getString("qrURL"));
                }
                params2.put("respCode", resJo.getString("respCode"));
                params2.put("respMsg", resJo.getString("respMsg"));
                if (resJo.containsKey("showPage")) {
                    params2.put("showPage", resJo.getString("showPage"));
                }

                params2.put("version", resJo.getString("version"));
                //params2.put("subAppId", resJo.getString("subAppId"));
                myRSign = Safe.sign(params2);
                rSign = resJo.getString("sign");
                Map<String, String> resultMap = new HashMap<>();
		/*if (!myRSign.equals(rSign)) {
			resultMap.put("payState", "fail");
			resultMap.put("message", "签名异常，支付失败!");
			resultMap.put("payUrl", resJo.getString("payInfo"));
		} else {*/
                if ("00".equals(resJo.getString("respCode"))) {

                    String payUrl = resJo.getString("payInfo");
                    JSONObject jsonObject =JSONObject.parseObject(payUrl);
                    System.out.println("payUrl=======" + payUrl);
                    System.out.println("jsonObject=======" + jsonObject);
                    //map.put("payState", "success");
                    //map.put("payUrl", payUrl);
                    map.put("status", "WECHAT_PAY");
                    resultMap.put("appId", jsonObject.getString("appId"));
                    resultMap.put("timeStamp", jsonObject.getString("timeStamp"));
                    resultMap.put("paySign", jsonObject.getString("paySign"));
                    resultMap.put("nonceStr", jsonObject.getString("nonceStr"));
                    resultMap.put("package", jsonObject.getString("package"));
                    resultMap.put("signType", jsonObject.getString("signType"));
                    orderDTO.setJsConfig(resultMap);
                    map.put("payMsg", "订单创建成功");
                    map.put("result", orderDTO);
                    return map;
                    // response.sendRedirect(payUrl);
                }
            /*case HYFMINI:
                JSONArray jsonArray = new JSONArray();
                //String payType = request.getParameter("payType");
                String body = "测试商品名称";
                try {
                    body = new String(body.getBytes("UTF-8"), "ISO-8859-1");
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                orderInfo = storeOrderService.getOrderInfo(orderId,null);
                if(ObjectUtil.isNull(orderInfo)) {
                    throw new YshopException("订单不存在");
                }
                if(orderInfo.getPaid().equals(OrderInfoEnum.PAY_STATUS_1.getValue())) {
                    throw new YshopException("该订单已支付");
                }

                if(orderInfo.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
                    throw new YshopException("该支付无需支付");
                }
                String appid = WxPayConfig.appid;// 小程序ID

                String mch_id = WxPayConfig.mch_id;// 商户号

                String nonce_str = UUIDHexGenerator4wechat.generate();// 随机字符串

                String today = new SimpleDateFormat("yyyyMMddHHmmss")
                        .format(new Date());

                String code = PayUtil4wechat.createCode(8);

                String out_trade_no = mch_id + today + code;// 商户订单号

                String spbill_create_ip = "192.168.0.1";// 终端IP

                String notify_url = WxPayConfig.notify_url;// 通知地址

                String trade_type = WxPayConfig.TRADETYPE;// 交易类型
                YxUser yxUser = yxUserService.getById(uid);
                WechatUserDto wechatUser = yxUser.getWxProfile();
                String openid = wechatUser.getRoutineOpenid();
                *//*String openid = request.getParameter("openid");
                return map;
                String userDefine2 = request.getParameter("userDefine2");
                String banlaceSum = request.getParameter("banlaceSum");*//*
                String banlaceSum = "0.01";
                int banlaceSum1 = (new BigDecimal(banlaceSum).multiply(new BigDecimal(
                        100))).intValue();
                banlaceSum = Integer.toString(banlaceSum1);
                *//**//*

                PaymentPo4wechat paymentPo = new PaymentPo4wechat();

                paymentPo.setAppid(appid);

                paymentPo.setMch_id(mch_id);

                paymentPo.setNonce_str(nonce_str);

                String newbody = null;
                try {
                    newbody = new String(body.getBytes("ISO-8859-1"), "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }// 以utf-8编码放入paymentPo，微信支付要求字符编码统一采用UTF-8字符编码

                paymentPo.setBody(newbody);

                paymentPo.setOut_trade_no(out_trade_no);

                paymentPo.setTotal_fee(banlaceSum);

                paymentPo.setSpbill_create_ip(spbill_create_ip);

                paymentPo.setNotify_url(notify_url);

                paymentPo.setTrade_type(trade_type);

                paymentPo.setOpenid(openid);

                // 把请求参数打包成数组

                Map sParaTemp = new HashMap();

                sParaTemp.put("appid", paymentPo.getAppid());

                sParaTemp.put("mch_id", paymentPo.getMch_id());

                sParaTemp.put("nonce_str", paymentPo.getNonce_str());

                sParaTemp.put("body", paymentPo.getBody());

                sParaTemp.put("out_trade_no", paymentPo.getOut_trade_no());

                sParaTemp.put("total_fee", paymentPo.getTotal_fee());

                sParaTemp.put("spbill_create_ip", paymentPo.getSpbill_create_ip());

                sParaTemp.put("notify_url", paymentPo.getNotify_url());

                sParaTemp.put("trade_type", paymentPo.getTrade_type());

                sParaTemp.put("openid", paymentPo.getOpenid());

                // 除去数组中的空值和签名参数

                Map sPara = PayUtil4wechat.paraFilter(sParaTemp);

                String prestr = PayUtil4wechat.createLinkString(sPara); // 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串

                String key = "&key=" + WxPayConfig.key; // 商户支付密钥

                // MD5运算生成签名

                String mysign = PayUtil4wechat.sign(prestr, key, "utf-8").toUpperCase();

                paymentPo.setSign(mysign);

                // 打包要发送的xml

                // String respXml = MessageUtil4wechat.messageToXML(paymentPo);
                String respXml = "<xml>" + "<appid>" + paymentPo.getAppid()
                        + "</appid>"

                        + "<body><![CDATA[" + paymentPo.getBody() + "]]></body>"

                        + "<mch_id>" + paymentPo.getMch_id() + "</mch_id>"

                        + "<nonce_str>" + paymentPo.getNonce_str() + "</nonce_str>"

                        + "<notify_url>" + paymentPo.getNotify_url() + "</notify_url>"

                        + "<openid>" + paymentPo.getOpenid() + "</openid>"

                        + "<out_trade_no>" + paymentPo.getOut_trade_no()
                        + "</out_trade_no>"

                        + "<spbill_create_ip>" + paymentPo.getSpbill_create_ip()
                        + "</spbill_create_ip>"

                        + "<total_fee>" + paymentPo.getTotal_fee() + "</total_fee>"

                        + "<trade_type>" + paymentPo.getTrade_type() + "</trade_type>"

                        + "<sign>" + paymentPo.getSign() + "</sign>"

                        + "</xml>";

                // 打印respXml发现，得到的xml中有“__”不对，应该替换成“_”

                respXml = respXml.replace("__", "_");

                String urlMini = WxPayConfig.pay_url;// 统一下单API接口链接

                String param = respXml;

                // String result = SendRequestForUrl.sendRequest(url, param);//发起请求

                String result = PayUtil4wechat.httpRequest(urlMini, "POST", param);

                // 将解析结果存储在HashMap中

                Map<String, String> mapResult = new HashMap();

                InputStream in = new ByteArrayInputStream(result.getBytes());

                // 读取输入流

                SAXReader reader = new SAXReader();

                Document document = null;
                try {
                    document = reader.read(in);
                } catch (DocumentException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                // 得到xml根元素

                Element root = document.getRootElement();

                // 得到根元素的所有子节点

                @SuppressWarnings("unchecked")
                List<Element> elementList = root.elements();

                for (Element element : elementList) {

                    mapResult.put(element.getName(), element.getText());

                }

                // 返回信息

                String return_code = mapResult.get("return_code");// 返回状态码

                String return_msg = mapResult.get("return_msg");// 返回信息

                System.out.println("return_msg" + return_msg);

                JSONObject JsonObject = new JSONObject();
                Map<String, String> resultMap = new HashMap<>();
                if (return_code == "SUCCESS" || return_code.equals(return_code)) {

                    // 业务结果

                    String prepay_id = mapResult.get("prepay_id");// 返回的预付单信息

                    String nonceStr = UUIDHexGenerator4wechat.generate();

                    JsonObject.put("nonceStr", nonceStr);

                    JsonObject.put("package", "prepay_id=" + prepay_id);

                    Long timeStamp = System.currentTimeMillis() / 1000;

                    JsonObject.put("timeStamp", timeStamp + "");

                    String stringSignTemp = "appId=" + appid + "&nonceStr=" + nonceStr
                            + "&package=prepay_id=" + prepay_id
                            + "&signType=MD5&timeStamp=" + timeStamp;

                    // 再次签名

                    String paySign = PayUtil4wechat.sign(stringSignTemp, key, "utf-8")
                            .toUpperCase();

                    JsonObject.put("paySign", paySign);

                    jsonArray.add(JsonObject);


                    *//*Company company = null;
                    User loginUser = userService.checkOpenId(openid);
                    if (loginUser == null) {
                        resultMap.put("loginState", "fail");
                    } else {
                        company = companyService.selectByPrimaryKey(loginUser
                                .getCompanyId());
                        resultMap.put("loginState", "success");
                    }
                    Recharge vo = new Recharge();
                    vo.setUserId(loginUser.getUserId());
                    vo.setRechargeBillId(UUID.randomUUID().toString());
                    vo.setCompanyId(company.getCompanyId());
                    vo.setCompanyName(company.getCompanyName());
                    vo.setBillAmount(new BigDecimal(banlaceSum).divide(new BigDecimal(100)));
                    vo.setUserName(loginUser.getUserName());
                    vo.setUserDefine2(userDefine2);
                    vo.setBillState("0"); // 0-待充值 1-充值中 2-到账成功 3-失败 4-已支付
                    vo.setIsDelete("0"); // 删除状态 0-正常使用 1-删除
                    vo = rechargeService.insertSelective(vo);*//*

                    *//*Map hdmap = new HashMap();
                    hdmap.put("rechargeBillId", vo.getRechargeBillId());
                    hdmap.put("payType", payType);
                    if (payType != null && payType.equals("batch")) {
                        String returnBackIds = request.getParameter("returnBackIds")
                                .replace("[", "").replace("]", "")
                                .replaceAll("\"", "'");
                        String returnNos = request.getParameter("returnNos")
                                .replace("[", "").replace("]", "")
                                .replaceAll("\"", "'");
                        hdmap.put("returnBackIds", returnBackIds);
                        hdmap.put("returnNos", returnNos);
                        System.out.println("signid写入：" + paymentPo.getMch_id()
                                + "==================" + returnBackIds);
                    }else if (payType != null && payType.equals("policy")) {

                    } else {
                        String returnBackId = request.getParameter("returnBackId");
                        hdmap.put("returnBackId", returnBackId);
                    }*//*
                    // servletContext.setAttribute(paymentPo.getMch_id(),
                    // vo.getRechargeBillId()+","+returnBackId);
                    //servletContext.setAttribute(paymentPo.getMch_id(), hdmap);
                    //SpringContextUtils.applicationContext.setAttribute(paymentPo.getMch_id();
                    ShoppingPayform pfMini = new ShoppingPayform();
                    pfMini.setTotalprice(orderInfo.getPayPrice());
                    pfMini.setDeletestatus(false);
                    pfMini.setUid(uid);
                    pfMini.setPayType("小程序汇卡支付");
                    pfMini.setPayno(System.currentTimeMillis()+"-"+orderId);
                    pfMini.setOrderId(orderId);
                    pfMini.setPaystatus("未支付");
                    shoppingPayformService.save(pfMini);
                    String redisKey = String.valueOf(StrUtil.format("{}{}",
                            "hyfMiniNotify", orderInfo.getId()));
                    redisTemplate.opsForValue().set(redisKey, pfMini.getPayno() ,
                            ShopConstants.ORDER_OUTTIME_UNPAY, TimeUnit.MINUTES);
                    resultMap.put("status", "WECHAT_PAY");
                    resultMap.put("appId", appid);
                    resultMap.put("timeStamp", timeStamp.toString());
                    resultMap.put("paySign", paySign);
                    resultMap.put("nonceStr", nonceStr);
                    resultMap.put("package", "prepay_id=" + prepay_id);
                    resultMap.put("signType", WxPayConfig.SIGNTYPE);
                    orderDTO.setJsConfig(resultMap);
                    map.put("payMsg", "订单创建成功");
                    map.put("result", orderDTO);
                }
                return map;*/
        }

        map.put("payMsg","订单生成失败");
        return map;
    }




}
